<template>
  <div class="pagination-table">
    <el-table
      v-loading="loading"
      :data="tableData"
      :max-height="maxHeight"
      v-bind="$attrs"
      @selection-change="handleSelectionChange"
    >
      <el-table-column
        v-if="showIndex"
        type="index"
        :label="indexLabel"
        :width="indexWidth"
        align="center"
        fixed="left"
      />
      <slot />
    </el-table>

    <div class="pagination-wrapper" v-if="showPagination">
      <el-pagination
        v-model:current-page="pagination.pageNum"
        v-model:page-size="pagination.pageSize"
        :page-sizes="pageSizes"
        :total="pagination.total"
        :layout="paginationLayout"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, watch, computed, onMounted } from 'vue'
import { ElTable, ElPagination, ElTableColumn } from 'element-plus'

interface Props {
  query: (params: any) => Promise<any>
  queryParams: Record<string, any>
  showPagination?: boolean
  pageSizes?: number[]
  paginationLayout?: string
  dataField?: string
  totalField?: string
  autoLoad?: boolean
  data?: any[]
  total?: number
  showIndex?: boolean
  indexLabel?: string
  indexWidth?: number
  maxHeight?: string | number
}

interface Emits {
  (e: 'update:data', data: any[]): void
  (e: 'update:total', total: number): void
  (e: 'selection-change', selection: any[]): void
  (e: 'load-success', data: any[], total: number): void
  (e: 'load-error', error: any): void
}

const props = withDefaults(defineProps<Props>(), {
  showPagination: true,
  pageSizes: () => [10, 20, 50, 100],
  paginationLayout: 'total, sizes, prev, pager, next, jumper',
  dataField: 'records',
  totalField: 'total',
  autoLoad: true,
  data: () => [],
  total: 0,
  showIndex: true,
  indexLabel: '序号',
  indexWidth: 60,
  maxHeight: undefined
})

const emit = defineEmits<Emits>()

const loading = ref(false)
const tableData = ref<any[]>([])
const selectedRows = ref<any[]>([])

const pagination = reactive({
  pageNum: 1,
  pageSize: 10,
  total: 0
})

const currentQueryParams = computed(() => ({
  pageNum: pagination.pageNum,
  pageSize: pagination.pageSize,
  ...props.queryParams
}))

const maxHeight = computed(() => {
  return props.maxHeight || undefined
})

watch(
  () => props.queryParams,
  () => {
    if (props.autoLoad) {
      pagination.pageNum = 1
      loadData()
    }
  },
  { deep: true }
)

watch(
  () => props.data,
  (newData) => {
    if (newData && Array.isArray(newData) && newData.length > 0) {
      tableData.value = newData
    } else {
      tableData.value = []
    }
  },
  { immediate: true }
)

watch(
  () => props.total,
  (newTotal) => {
    if (typeof newTotal === 'number' && newTotal >= 0) {
      pagination.total = newTotal
    } else {
      pagination.total = 0
    }
  },
  { immediate: true }
)

const loadData = async () => {
  if (!props.query) return

  loading.value = true
  try {
    const res = await props.query(currentQueryParams.value)

    let data: any[] = []
    let total = 0

    // 确保 res 不为 null 或 undefined
    if (res && typeof res === 'object') {
      // 处理 IResponse 结构 (code, data)
      if (res.code !== undefined && res.data !== undefined) {
        const responseData = res.data
        if (responseData && typeof responseData === 'object') {
          if (responseData[props.dataField] && Array.isArray(responseData[props.dataField])) {
            data = responseData[props.dataField]
            total = responseData[props.totalField] || 0
          } else if (Array.isArray(responseData)) {
            data = responseData
            total = responseData.length
          }
        }
      } else if (res.data && typeof res.data === 'object') {
        // 如果响应被包装在data字段中
        const responseData = res.data
        if (responseData[props.dataField] && Array.isArray(responseData[props.dataField])) {
          data = responseData[props.dataField]
          total = responseData[props.totalField] || 0
        } else if (Array.isArray(responseData)) {
          data = responseData
          total = responseData.length
        }
      } else if (res[props.dataField] && Array.isArray(res[props.dataField])) {
        data = res[props.dataField]
        total = res[props.totalField] || 0
      } else if (Array.isArray(res)) {
        data = res
        total = res.length
      }
    }

    // 确保数据是数组类型
    if (!Array.isArray(data)) {
      data = []
    }

    tableData.value = data
    pagination.total = total || 0

    emit('update:data', data)
    emit('update:total', total || 0)
    emit('load-success', data, total || 0)
  } catch (error) {
    console.error('加载数据失败:', error)
    tableData.value = []
    pagination.total = 0
    emit('load-error', error)
  } finally {
    loading.value = false
  }
}

const handleQuery = () => {
  pagination.pageNum = 1
  loadData()
}

const resetQuery = () => {
  pagination.pageNum = 1
  loadData()
}

const handleSizeChange = (size: number) => {
  pagination.pageSize = size
  pagination.pageNum = 1
  loadData()
}

const handleCurrentChange = (page: number) => {
  pagination.pageNum = page
  loadData()
}

const handleSelectionChange = (selection: any[]) => {
  selectedRows.value = selection
  emit('selection-change', selection)
}

const getSelectedRows = () => {
  return selectedRows.value
}

const getSelectedIds = (idField = 'id') => {
  return selectedRows.value.map((row) => row[idField]).filter(Boolean)
}

const clearSelection = () => {
  selectedRows.value = []
}

defineExpose({
  loadData,
  handleQuery,
  resetQuery,
  getSelectedRows,
  getSelectedIds,
  clearSelection,
  pagination
})

onMounted(() => {
  if (props.autoLoad) {
    loadData()
  }
})
</script>

<style lang="less" scoped>
.pagination-table {
  .pagination-wrapper {
    margin-top: 16px;
    display: flex;
    justify-content: flex-end;
  }
}
</style>
